/*
  The lock.c file defines locking and unlocking primitives.
*/

#include <types.h>
#include <klib.h>
#include <i386_arch.h>
#include <i386_pmode.h>
#include <spinlock.h>
#include <scheduler.h>


/* Initialize lock */
void lock_initialize(volatile int *p)
  {
    spinlock_init(p);
  }

/* Acquire lock */
void lock_acquire(volatile int *p)
  {
    while(test_and_set(1,p)==1)
	// do nothing... could schedule maybe?
      ;

  }

/* Release lock */
void lock_release(volatile int *p)
  {
    test_and_set(0,p);
  }



// Acquire lock, disable interrupts and return previous interrupt status 
int lock_acquire_cli(volatile int *p)
  {
    int hwi;  // hardware interrupts

    hwi=read_if();
    disable_interrupts();
    while(test_and_set(1,p)==1)
	// do nothing... could schedule maybe?
      ;

    return hwi;
  }

// Release lock and enable interrupt according to hwi variable 
void lock_release_sti(volatile int *p,int hwi)
  {
    test_and_set(0,p);
    if (hwi)
      enable_interrupts();
  }


/*
int lock_acquire_cli(volatile int *p)
  {
    int hwi;  // hardware interrupts

    hwi=read_if();
    asm("cli");
    
    // it's busy
    while(test_and_set(1,p)==1)
      {	
	if (hwi)
	  {
	    schedule();
	    asm("sti");
	    // allow for an interrupt
	    asm("nop");
	    asm("cli");
	  }
      }


    if (hwi)
      asm("sti");

    return hwi;
  }

void lock_release_sti(volatile int *p,int hwi)
  {
    int hwi;  // hardware interrupts

    hwi=read_if();
    asm("cli");

    test_and_set(0,p);

    if (hwi)
      asm("sti");
  }
*/
